<?php
namespace core\models;
/**
 * 目录\文件处理
 * @author Howard
 */
class DirFile {
    /**
     * 目录\文件处理
     * @author Howard
     */
    public function __construct() {
    }

    /**
     * 取得目录下的所有文件
     * @param string $dir    目录
     * @param string $suffix 文件扩展名，如：.txt
     * @return array 返回文件名数组
     */
    public function getFiles($dir, $suffix = '') {
        $d = array();
        if (!is_dir($dir))
            return $d;
        $hand = opendir($dir);
        while (false !== ($file = readdir($hand))) {
            if ($file != '.' && $file != '..' && is_file(preg_replace('/\/$/', '', $dir) . '/' . $file)) {
                if ($suffix && !preg_match('/' . preg_quote($suffix) . '$/i', $file)) {
                    continue;
                }
                $d[] = $file;
            }
        }
        closedir($hand);
        return $d;
    }

    /**
     * 取得目录下的所有文件夹
     * @param string $dir    目录
     * @return array 返回文件夹名称数组
     */
    public function getDirs($dir) {
        $d = array();
        if (!is_dir($dir)) return $d;
        $hand = opendir($dir);
        while (false !== ($file = readdir($hand))) {
            if ($file != '.' && $file != '..' && is_dir($dir . '/' . $file)) {
                $d[] = $file;
            }
        }
        closedir($hand);
        return $d;
    }

    /**
     * 创建目录 ,支持多层
     * @param string $path 目录路径
     * @param int    $mode 目录权限 默认0777
     * @return bool
     * @author lwkai
     * @date   2014-5-27
     */
    public function createDir($path, $mode = 0777) {
        if (!is_dir($path)) {
            return @mkdir($path, $mode, true);
        }
        return true;
    }

    /**
     * 取得文件扩展名
     * @param string $filename 文件绝对路径
     * @return int|string 如果无法取得扩展名则返回数字值。
     * @author lwkai
     * @date   2014-10-20
     * @todo 有bug，如无法识别.docx, .html这些文件
     */
    public function getFileExt($filename) {
        if (!file_exists($filename)) return '';
        $fileType = self::getFileType($filename);
        if ($fileType == '') {
            $file = fopen($filename, "rb");
            $bin  = fread($file, 2); //只读2字节
            fclose($file);
            $strInfo  = @unpack("C2chars", $bin);
            $fileType = intval($strInfo['chars1'] . $strInfo['chars2']);
        }
        return $fileType;
    }

    /**
     * 取得文件真实类型
     * @param $filename
     * @return string
     * @author lwkai
     * @todo 有bug，如无法识别.docx, .html这些文件
     * @date   2014-6-26
     */
    public function getFileType($filename) {
        if (!file_exists($filename)) return '';
        $file = fopen($filename, "rb");
        $bin  = fread($file, 2); //只读2字节
        fclose($file);
        $strInfo  = @unpack("C2chars", $bin);
        $typeCode = intval($strInfo['chars1'] . $strInfo['chars2']);
        switch ($typeCode) {
            case 7790:
                $fileType = 'exe';
                break;
            case 7784:
                $fileType = 'midi';
                break;
            case 8297:
                $fileType = 'rar';
                break;
            case 255216:
                $fileType = 'jpg';
                break;
            case 7173:
                $fileType = 'gif';
                break;
            case 6677:
                $fileType = 'bmp';
                break;
            case 13780:
                $fileType = 'png';
                break;
            case 9168:
                $fileType = 'ini';
                break;
            case 3780:
                $fileType = 'pdf';
                break;
            case 208207:
            case 60116:
                $fileType = 'doc';
                break;
            case 8075:
                $fileType = 'zip';
                break;
            case 6980:
                $fileType = 'mdi';
                break;
            case 6787:
                $fileType = 'swf';
                break;
            case 208242:
                $fileType = 'csv';
                break;
            default:
                $fileType = '';
            //echo 'unknown';
        }
        return $fileType;
    }

    /**
     * 检查文件夹是否有写入权限
     * @param string $path  目录路径
     * @return bool
     * @author lwkai
     * @date   2016-7-19
     */
    public function isWritable($path){
        if (strtolower(substr(PHP_OS, 0, 3)) === 'win') {
            if (file_exists($path)) {
                $path = realpath($path);
                if (is_dir($path)) {
                    $result = @tempnam($path, 'osc');
                    if (is_string($result) && file_exists($result)) {
                        unlink($result);
                        return (strpos($result, $path) === 0) ? true : false;
                    }
                } else {
                    $handle = @fopen($path, 'r+');
                    if (is_resource($handle)) {
                        fclose($handle);
                        return true;
                    }
                }
            } else{
                $dir = dirname($path);
                if (file_exists($dir) && is_dir($dir) && self::isWritable($dir)) {
                    return true;
                }
            }
            return false;
        } else {
            return is_writable($path);
        }
    }

    /**
     * 复制文件或文件夹到新位置【增强型】
     * @param string $src 源文件（夹）
     * @param string $des 目标文件（夹）
     * @author Howard
     * @return bool
     */
    public function copy($src, $des) {
        if(is_file($src)){
            return copy($src, $des);
        }else {
            $dir = opendir($src);
            @mkdir($des);
            while (false !== ($file = readdir($dir))) {
                if (($file != '.') && ($file != '..')) {
                    if (is_dir($src . '/' . $file)) {
                        $this->copy($src . '/' . $file, $des . '/' . $file);
                    } else {
                        copy($src . '/' . $file, $des . '/' . $file);
                    }
                }
            }
            closedir($dir);
            return 0;
        }
    }

    /**
     * 删除目录
     * 注意：非空目录也可删除
     * @author Howard
     * @param string $dirName 要删除的目录路径（只能是当前框架下的路径）。如当前框架根路径为/var/abc，那么$dirName必须是以/var/abc开头的路径方可被删除。
     * @return bool
     */
    public function delDir($dirName){
        if(!is_dir($dirName) || strpos($dirName, Z_DIR) !== 0){
            return false;
        }
        $handle = @opendir($dirName);
        while(($file = @readdir($handle)) !== false){
            if($file != '.' && $file != '..'){
                $dir = $dirName . '/' . $file;
                is_dir($dir) ? $this->delDir($dir) : @unlink($dir);
            }
        }
        closedir($handle);
        return rmdir($dirName) ;
    }

    /**
     * 删除文件
     * @param String $file 文件绝对地址
     * @author liwenkai <1275124829@163.com>
     * @date 2020/12/30 13:50
     */
    public function delFile($file) {
        if (is_file($file)) {
            @unlink($file);
        }
    }
}